package org.budo.icbc.sdk.impl;

import java.lang.reflect.Constructor;

import org.budo.icbc.sdk.IcbcSdk;
import org.budo.icbc.sdk.entity.EAccountOpenReq;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.time.Time;

/**
 * @author limingwei
 */
public class IcbcSdkImpl implements IcbcSdk {

    @Override
    public String eAccountOpen(EAccountOpenReq req) {
        Class<?> uiIcbcClientType = ReflectUtil.classForName("com.icbc.api.UiIcbcClient");
        Object client = this.newUiIcbcClient(uiIcbcClientType, req);

        String bizType = "com.icbc.api.request.EaccountManageRequestV1$EaccountManageRequestBizV1";
        Class<?> bizClazz = ReflectUtil.classForName(bizType);
        Object biz = ReflectUtil.newInstance(bizClazz);

        ReflectUtil.invokeMethod(bizClazz, "setUserId", new Class[] { String.class }, biz, new Object[] { req.getUserId() });
        ReflectUtil.invokeMethod(bizClazz, "setCorpAppid", new Class[] { String.class }, biz, new Object[] { req.getAppId() });
        ReflectUtil.invokeMethod(bizClazz, "setOrderTimeStamp", new Class[] { String.class }, biz, new Object[] { Time.now().toString("yyyyMMddhhmmss") });

        String reqType = "com.icbc.api.request.EaccountManageRequestV1";
        Class<?> reqClazz = ReflectUtil.classForName(reqType);
        Object request = ReflectUtil.newInstance(reqClazz);

        ReflectUtil.invokeMethod(reqClazz, "setServiceUrl", new Class[] { String.class }, request, new Object[] { req.getApiUrl() });

        Class bizContentType = ReflectUtil.classForName("com.icbc.api.BizContent");
        ReflectUtil.invokeMethod(reqClazz, "setBizContent", new Class[] { bizContentType }, request, new Object[] { biz });

        Class icbcRequestType = ReflectUtil.classForName("com.icbc.api.IcbcRequest");
        String form = (String) ReflectUtil.invokeMethod(uiIcbcClientType, "buildPostForm", new Class[] { icbcRequestType }, client, new Object[] { request });
        return form;
    }

    private Object newUiIcbcClient(Class<?> uiIcbcClientType, EAccountOpenReq req) {
        Class<?>[] parameterTypes = { String.class, String.class, String.class, String.class, String.class, String.class };
        Constructor<?> constructor = ReflectUtil.getConstructor(uiIcbcClientType, parameterTypes);

        Object[] args = { req.getAppId(), req.getSignType(), req.getRsaPrivateKey(), req.getCharset(), req.getEncryptType(), req.getAesKey() };
        Object client = ReflectUtil.newInstance(constructor, args);
        return client;
    }
}
